package com.example.cash.craft.service.impl;

import com.example.cash.craft.dao.persist.repository.*;
import com.example.cash.craft.exception.ServiceException;
import com.example.cash.craft.pojo.core.CurrentPrincipal;
import com.example.cash.craft.pojo.entity.*;
import com.example.cash.craft.pojo.param.OrderAddNewParam;
import com.example.cash.craft.pojo.vo.*;
import com.example.cash.craft.service.IOrderService;
import com.example.cash.craft.web.StateCode;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;

@Service
public class OrderServiceImpl implements IOrderService {

    @Value("${cash-craft.config.default-page-size}")
    private Integer defaultPageSize;
    @Autowired
    private IUserRepository userRepository;
    @Autowired
    private IProductRepository productRepository;
    @Autowired
    private IOrderRepository orderRepository;
    @Autowired
    private IOrderItemRepository orderItemRepository;
    @Autowired
    private IRewardPointsLogRepository rewardPointsLogRepository;

    @Override
    public void addNew(OrderAddNewParam param, CurrentPrincipal currentPrincipal) {
        // 验证会员积分是否充足
        Long userId = currentPrincipal.getId();
        UserVO user = userRepository.selectById(userId);
        Integer rewardPoints = user.getRewardPoints();
        if (rewardPoints < param.getRewardPointsUsed()) {
            throw new ServiceException(StateCode.ERROR_BAD_REQUEST, "会员积分不足");
        }

        // 验证商品是否存在，验证商品库存
        Long[] productIdList = param.getProductIdList();
        Integer[] quantityList = param.getQuantityList();
        ProductVO[] productList = new ProductVO[productIdList.length];
        BigDecimal totalAmount = new BigDecimal(0);
        for (int i = 0; i < productIdList.length; i++) {
            Long productId = productIdList[i];
            ProductVO product = productRepository.selectById(productId);
            if (product == null) {
                throw new ServiceException(StateCode.ERROR_NOT_FOUND, "商品不存在");
            }
            if (product.getStock() < quantityList[i]) {
                throw new ServiceException(StateCode.ERROR_BAD_REQUEST, "商品【" + product.getTitle() + "】库存不足");
            }
            productList[i] = product;
            totalAmount = totalAmount.add(product.getPrice().multiply(new BigDecimal(quantityList[i])));
        }

        // 计算订单实际支付金额
        BigDecimal actualPaymentAmount = totalAmount.subtract(new BigDecimal(param.getRewardPointsUsed()));

        // 创建订单
        Order order = new Order();
        order.setUserId(userId);
        order.setRewardPointsUsed(param.getRewardPointsUsed());
        order.setTotalAmount(totalAmount);
        order.setActualPaymentAmount(actualPaymentAmount);
        order.setStatus(Order.Status.UNPAID.getValue());
        orderRepository.insert(order);

        // 更新商品库存、销量，创建订单项
        for (int i = 0; i < productIdList.length; i++) {
            if (quantityList[i] < 1) {
                continue;
            }

            Product productForUpdate = new Product();
            productForUpdate.setId(productIdList[i]);
            productForUpdate.setStock(productList[i].getStock() - quantityList[i]);
            productForUpdate.setSales(productList[i].getSales() + quantityList[i]);
            productRepository.updateById(productForUpdate);

            OrderItem orderItem = new OrderItem();
            orderItem.setOrderId(order.getId());
            orderItem.setProductId(productIdList[i]);
            orderItem.setProductCoverImage(productList[i].getCoverImage());
            orderItem.setProductTitle(productList[i].getTitle());
            orderItem.setProductPrice(productList[i].getPrice());
            orderItem.setProductQuantity(quantityList[i]);
            orderItemRepository.insert(orderItem);
        }

        // 创建会员积分变动记录
        if (param.getRewardPointsUsed() > 0) {
            RewardPointsLog rewardPointsLog = new RewardPointsLog();
            rewardPointsLog.setUserId(userId);
            rewardPointsLog.setOrderId(order.getId());
            rewardPointsLog.setPointsChange(-param.getRewardPointsUsed());
            rewardPointsLog.setDescription(RewardPointsLog.Description.CONSUME_DEDUCTION.getDescription());
            rewardPointsLogRepository.insert(rewardPointsLog);

            User userForUpdate = new User();
            userForUpdate.setId(userId);
            userForUpdate.setRewardPoints(rewardPoints - param.getRewardPointsUsed());
            userRepository.updateById(userForUpdate);
        }
    }

    @Override
    public OrderFullInfoVO selectById(Long id, CurrentPrincipal currentPrincipal) {
        OrderSimpleInfoVO findResult = orderRepository.selectById(id);
        if (findResult == null) {
            throw new ServiceException(StateCode.ERROR_NOT_FOUND, "订单不存在");
        }

        if (!findResult.getUserId().equals(currentPrincipal.getId())) {
            throw new ServiceException(StateCode.ERROR_FORBIDDEN, "无权限访问");
        }

        List<OrderItemVO> orderItems = orderItemRepository.listByOrderId(id);

        OrderFullInfoVO order = new OrderFullInfoVO();
        BeanUtils.copyProperties(findResult, order);
        order.setOrderItemList(orderItems);
        return order;
    }

    @Override
    public PageData<OrderSimpleInfoVO> listByUser(Integer page, CurrentPrincipal currentPrincipal) {
        PageData<OrderSimpleInfoVO> pageData = orderRepository.listByUserId(currentPrincipal.getId(), page, defaultPageSize);
        return pageData;
    }

}
